import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:dio/dio.dart';
import 'package:flutter/services.dart';
import 'package:image_gallery_saver/image_gallery_saver.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:url_launcher/url_launcher.dart';

import '../../../https/index.dart';
import '../../config/index.dart';
import '../../utils/index.dart';
import '../index.dart';
import '../state/base_state.dart';

abstract class BaseViewModel extends ChangeNotifier
    with
        ViewModelRequestMixin,
        NavigatorMixin,
        ToastMixin,
        EventBusMixin,
        SharedPreferenceMixin {
  ViewState _viewState = ViewState.init;

  BaseViewModel({ViewState? viewState})
      : _viewState = viewState ?? ViewState.init;

  void setViewState(ViewState viewState) {
    _viewState = viewState;
    notifyListeners();
  }

  ViewState get viewState => _viewState;

  /// state
  late BaseState _baseState;

  BaseState get baseState => _baseState;

  /// 注册state
  void registerState(BaseState state) {
    _baseState = state;
  }

  BuildContext getContext() {
    if (!baseState.mounted) {
      throw "获取context失败，请检查调用context的时机，最早在initEventsForContext这边调用";
    }
    return context;
  }

  /// 上来初始化的数据（大部分是请求接口 其他的操作不保证不出问题）
  void initData() {}

  /// 生命周期的操作 ---- initState
  void viewModelInit() {}

  /// 生命周期的操作 ---- initState 中获取到context的操作
  void viewModelInitForContext(BuildContext context) {}

  /// 生命周期的操作 reassemble
  void reassemble() {}

  /// 销毁动作
  void viewModelDispose() {
    dispose();
  }

  /// 判断是否释放了资源
  bool _isDispose = false;

  bool get isDispose => _isDispose;

  bool get init => _viewState == ViewState.init;

  void setInit() {
    setViewState(ViewState.init);
  }

  bool get progress => _viewState == ViewState.progress;

  void setProgress() {
    setViewState(ViewState.progress);
  }

  bool get success => _viewState == ViewState.success;

  void setSuccess() {
    setViewState(ViewState.success);
  }

  bool get empty => _viewState == ViewState.empty;

  void setEmpty() {
    setViewState(ViewState.empty);
  }

  bool get responseError => _viewState == ViewState.responseError;

  void setResponseError({required String message}) {
    toast(message);
    setViewState(ViewState.responseError);
  }

  bool get httpError => _viewState == ViewState.httpError;

  void setHttpError() {
    toast('Http请求出错，请检查网络配置并且稍后再试');
    setViewState(ViewState.httpError);
  }

  bool get other => _viewState == ViewState.other;

  void setOther(msg) {
    toast(msg);
    setViewState(ViewState.other);
  }

  bool get noNet => _viewState == ViewState.noNet;

  void setNoNet({required String message}) {
    /// toast展示
    // toast(message);
    setViewState(ViewState.noNet);
  }

  /// 检查网络
  Future<bool> checkNet() async {
    var connectivityResult = await (Connectivity().checkConnectivity());
    return connectivityResult == ConnectivityResult.none;
  }

  @override
  Future<ResponseModel> sendRequest(RequestConfig config) async {
    try {
      final response = await HttpManager().request(config);
      final responseModel = ResponseModel.fromJson(response.data);
      return responseModel;
    } catch (e) {
      Log.e(e);
      if (e is DioException) {
        if (e is DioHttpError) {
          setHttpError();
        } else if (e is DioUnAuthorizedError) {
          /// 这里是走refreshToken的操作
          /// todo:::: refreshToken
          print('这里是走refreshToken的操作');
          print('e,message=${e.message}');
          print('e,error=${e.error}');
        } else {
          /// 这里一般是5xx错误 （如果出现了其他的问题，那就是代码的问题 自行排查）
          setOther(e.toString());
        }
      } else {
        /// 一般不可能走到这里 走到这里就是代码的问题 这里的dio问题 如果存在就是dio exception
        setOther(e.toString());
      }

      /// 全部再次抛出
      rethrow;
    }
  }

  void logd(String? msg) => debugPrint(msg);

  /// 保证刷新的时候provider不会销毁 销毁了便不再刷新
  @override
  void notifyListeners() {
    if (!_isDispose) {
      super.notifyListeners();
    }
  }

  @override
  void dispose() {
    super.dispose();
    _isDispose = true;
    Log.i("----$runtimeType  dispose----");
  }

  /// 封装popUtil
  void popUtilWithSwitchBottomNavBar({required int index}) {
    popUntil();

    /// 这里可以加入一些event_bus事件
  }

  /// 检查权限
  Future<bool> checkPermission({required Permission type}) async {
    bool isOk = false;

    /// 检查是否有权限
    if (await type.status != PermissionStatus.granted) {
      /// 没有权限就重新请求权限
      PermissionStatus status = await type.request();
      if (status == PermissionStatus.granted) {
        isOk = true;
      } else {
        await openAppSettings();
      }
    } else {
      isOk = true;
    }
    return isOk;
  }

  void launchTel(String mobile) async =>
      await UrlLaunchUtil().launchTel(mobile: mobile);

  void launchSms(String mobile) async =>
      await UrlLaunchUtil().launchSms(mobile: mobile);

  void launchBrowser(String url) async {
    if (await canLaunchUrl(Uri.parse(url))) {
      launchUrl(Uri.parse(url), mode: LaunchMode.externalApplication);
    }
  }

  /// 保存到相册
  void saveToPhoto({required String imageUrl, bool isAsset = false}) async {
    final value = await checkPermission(type: Permission.manageExternalStorage);
    if (!value) return;

    /// 保存的图片数据
    Uint8List imageBytes;
    if (isAsset) {
      /// 保存资源图片
      ByteData bytes = await rootBundle.load(imageUrl);
      imageBytes = bytes.buffer.asUint8List();
    } else {
      var response = await Dio()
          .get(imageUrl, options: Options(responseType: ResponseType.bytes));
      imageBytes = Uint8List.fromList(response.data);
    }
    final result = await ImageGallerySaver.saveImage(imageBytes);
    print(result);
    if (result != null && result['isSuccess']) {
      pop();
      toast("成功保存到相册");
    }
  }

  @override
  String toString() {
    return 'BaseModel{type: $runtimeType, _viewState: $_viewState}';
  }
}
